package ecarx.settings.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import com.malaysia.xui.adaptapi.Tribool;
import com.malaysia.xui.adaptapi.vehicle.sensor.ISensor;
import com.malaysia.xui.adaptapi.vehicle.sensor.ISensorEvent;

import ecarx.settings.function.CarFuncManager;
import ecarx.settings.function.VehicleFunctionManager;
import ecarx.settings.utils.SingleUtils;
import ecarx.settings.utils.SpSaveUtil;
import ecarx.settings.view.ShowModeDialogManager;

public class ShowModeReceiver extends BroadcastReceiver

        implements VehicleFunctionManager.SensorValueListener, VehicleFunctionManager.SensorSpeedListener, VehicleFunctionManager.FunctionEnableListener {

    private static final String TAG = ShowModeReceiver.class.getSimpleName();

    private static final String ACTION = "ecarx.settings.receiver.ShowModeReceiver";

    public static final String CACHE_STATUS_KEY = "ShowMode_Enabled";

    private static final int TOAST_DURATION = 5 * 1000;

    private final ShowModeDialogManager manager = ShowModeDialogManager.getInstance();

    private static final int MMI_ShowMode_ENABLED = 0x1;
    private static final int MMI_ShowMode_DISABLED = 0x2;

    private static volatile ShowModeReceiver listenerInstance; // 静态实例用于监听

    // ************************************************************************

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.d(TAG, "ShowModeReceiver onReceive function called with: intent = " + intent);

        if (intent == null || context == null) {
            Log.e(TAG, "ShowModeReceiver Received null intent or context");
            return;
        }

        // TODO 判断是否是当前Receiver需要处理的Action
        if (ACTION.equals(intent.getAction())) {

            boolean status = getCacheStatus();

            // TODO 如果展车模式未开启
            if (!status) {
                handleShowModeOnAction(context);
            }

            // TODO 如果处于展车模式中
            else {
                handleShowModeOffAction();
            }
        }
    }

    private void handleShowModeOnAction(Context context) {
        // TODO 信号条件是否满足打开弹窗条件
        if (validSignalConditionForEnableShowMode()) {

            // TODO 如果弹窗已打开不作操作
            if (isDialogOpening()) {
            } else {
                // TODO 打开弹窗
                openDialog(context);
            }
        } else {
            // TODO Toast提示原因
            showToast(context, "不能进入展车模式，请确认车辆状态", TOAST_DURATION);
        }
    }

    private void handleShowModeOffAction() {
        // TODO 信号条件是否满足关闭弹窗条件
        if (validSignalConditionForQuitShowMode()) {
            sendMMIAutoShowModset(MMI_ShowMode_DISABLED);
        } else {
            sendMMIAutoShowModset(MMI_ShowMode_ENABLED);
        }
    }

    // *******************************************************************************

    public static void initListenerInstance() {
        if (listenerInstance == null) {
            synchronized (ShowModeReceiver.class) {
                if (listenerInstance == null) {
                    listenerInstance = new ShowModeReceiver();
                    listenerInstance.registerSignalChangedListener();
                }
            }
        }
    }

    public static void destroyListener() {
        if (listenerInstance != null) {
            listenerInstance.unregisterSignalChangedListener();
            listenerInstance = null;
        }
    }

    // *****************************************************************************

    private boolean validSignalConditionForEnableShowMode() {
        return isPowerModeOn() && isGearP() && isSpeed0() && isVCUShowModeEnable() && isESCShowModeEnable();
    }

    private boolean validSignalConditionForQuitShowMode() {
        return isPowerModeOn() && isGearP();
    }

    // **********************************************************************************

    private boolean isGearP() {
        int gearStatus = CarFuncManager.getInstance().getSensorEvent(ISensor.SENSOR_TYPE_GEAR);
        return gearStatus == ISensorEvent.GEAR_PARK;
    }

    private boolean isPowerModeOn() {
        int state = VehicleFunctionManager.getInstance().getIgnSensor(ISensor.SENSOR_TYPE_IGNITION_STATE);
        return state == ISensorEvent.IGNITION_STATE_ON;
    }

    private boolean isSpeed0() {
        double speed = VehicleFunctionManager.getInstance().getSpeed();
        return speed == 0;
    }

    // TODO 带有布尔值性质的VCU_ShowModeEnable信号的获取
    private boolean isVCUShowModeEnable() {
//        return VehicleFunctionManager.getInstance().getFunctionEnable(ISettings.F_VCU_ShowModeEnable) == Tribool.yes;
        return true;
    }

    // TODO 带有布尔值性质的ESC_ShowModeEnable信号的获取
    private boolean isESCShowModeEnable() {
//        return VehicleFunctionManager.getInstance().getFunctionEnable(ISettings.F_ESC_ShowModeEnable) == Tribool.yes;
        return true;
    }

    // ***************************************************************

    private void sendMMIAutoShowModset(int mode) {
        VehicleFunctionManager.getInstance().setShowMode(mode);
        setCacheStatus(mode == MMI_ShowMode_ENABLED);
    }

    // ************************************************************************

    private void openDialog(Context context) {
        manager.setListener(new ShowModeDialogManager.DialogButtonListener() {

            @Override
            public void onCancelClicked() {
                sendMMIAutoShowModset(MMI_ShowMode_DISABLED);
            }

            @Override
            public void onOkClicked() {
                sendMMIAutoShowModset(MMI_ShowMode_ENABLED);

            }
        });
        manager.show(context);
    }

    private void closeDialog() {
        manager.dismiss();
    }

    private boolean isDialogOpening() {
        return manager.isShown();
    }

    // ***************************************************************************

    private void showToast(Context context, String message, int duration) {
        Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
        toast.setDuration(duration); // 设置为自定义时长
        toast.show();
    }

    // ***********************************************************************

    private boolean getCacheStatus() {
        return SpSaveUtil.getInstance(SingleUtils.get(Context.class)).getValueBoolean(CACHE_STATUS_KEY);
    }

    private void setCacheStatus(boolean status) {
        SpSaveUtil.getInstance(SingleUtils.get(Context.class)).saveValueBoolean(CACHE_STATUS_KEY, status);
    }

    // *************************************TODO 监听底层信号值的变化*********************

    private void registerSignalChangedListener() {

        VehicleFunctionManager.getInstance().addSensorValueListener(this);
        VehicleFunctionManager.getInstance().addSensorSpeedListener(this);
        VehicleFunctionManager.getInstance().addFunctionEnableListener(this);
    }

    private void unregisterSignalChangedListener() {
        VehicleFunctionManager.getInstance().removeSensorValueListener(this);
        VehicleFunctionManager.getInstance().removeSensorSpeedListener(this);
        VehicleFunctionManager.getInstance().removeFunctionEnableListener(this);
    }

    private void handleSignalChanged() {
        if (isDialogOpening()) {
            if (!validSignalConditionForEnableShowMode()) {
                closeDialog();
            }
        } else {

        }
    }

    @Override
    public void onSensorValueChanged(int sensor, int event) {

        // TODO 监听到档位值变化
        if (ISensor.SENSOR_TYPE_GEAR == sensor) {
            handleSignalChanged();
        }
        // TODO 监听到电源状态值变化
        if (ISensor.SENSOR_TYPE_IGNITION_STATE == sensor) {
            handleSignalChanged();
        }
    }

    @Override
    public void onSensorValueChanged(int sensor, float value) {
        // TODO 监听车速值变化
        if (ISensor.SENSOR_TYPE_CAR_SPEED == sensor) {
            handleSignalChanged();
        }
    }

    @Override
    public void onFunctionEnable(int functionId, Tribool enable) {
//        if (functionId == ISettings.F_VCU_ShowModeEnable || functionId == ISettings.F_ESC_ShowModeEnable) {
//            handleSignalChanged();
//        }
    }
}
